package data

import (
	"context"
	v1 "digitalhuman/api/produce/v1"
	pb "digitalhuman/api/storyboard/v1"
	"digitalhuman/internal/conf"
	"digitalhuman/models"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/transport/http"
	"github.com/wenqingqaq/backend-lib/tecmq"
	"strings"
	"time"
)

type ProduceData struct {
	config            *conf.Data
	produceHttpServer v1.ProduceHTTPClient
	data              *Data
	AssetData         *AssetData
}

func NewProduceData(c *conf.Data, d *Data, asset *AssetData) *ProduceData {
	// 创建一个http客户端
	httpClient, err := http.NewClient(context.Background(), http.WithEndpoint(c.ProduceServer.HttpAddr))
	if err != nil {
		log.Error("http.NewClient", err)
		return nil
	}
	produceHTTPClient := v1.NewProduceHTTPClient(httpClient)

	return &ProduceData{
		config:            c,
		produceHttpServer: produceHTTPClient,
		data:              d,
		AssetData:         asset,
	}
}

func (p *ProduceData) ReqProduceToNats(reply *pb.GetStoryboardReply) error {
	log.Info("nats 触发一个视频合成请求 storyId:", reply.Id)
	if reply.Id == 0 {
		log.Error("reply is nil")
		return nil
	}
	defer func(id int32) {
		if r := recover(); r != nil {
			log.Info("nats ReqProduceCreate Recovered in f", r, "id= ", id)
		}
	}(reply.Id)

	msg := tecmq.DigitalProduceMsg{
		Source:           tecmq.SourceDigital,
		Data:             make([]*tecmq.DigitalProduceMsgData, 0),
		SourceCreateTime: time.Now(),
	}
	// 拼装一下数据 发送给produce服务 生产请求
	for _, section := range reply.Sections {
		splitHuman := strings.Split(section.Human.Asset.Payload, ".")
		if section.Background.Asset.Thumbnail == "" || splitHuman[0] == "" || section.Text.Url == "" {
			log.Error("参数不全，无法生产视频 请检查数据是否完整 section_id = ", section.Id, "storyboard_id = ", reply.Id)
			return errors.New("参数不完整")
		}
		payloadB, err := json.Marshal(&v1.Payload{
			X:      section.Human.X,
			Y:      section.Human.Y,
			Width:  section.Human.Width,
			Height: section.Human.Height,
		})
		if err != nil {
			log.Error("payloadB Marshal is nil")
			return nil
		}
		msg.Data = append(msg.Data, &tecmq.DigitalProduceMsgData{
			StoryboardId:        reply.Id,
			StoryboardSectionId: section.Id,
			BackgroundUri:       section.Background.Asset.Thumbnail,
			FaceVideo:           splitHuman[0],
			AudionUri:           section.Text.Url,
			Payload:             string(payloadB),
		})
	}
	b, err := json.Marshal(msg)
	if err != nil {
		log.Error(err)
		return err

	}
	err = p.data.Nats.SendMsg(b)

	// 更新一下storyboard的状态为视频制作中 目前只有一个场景
	result := p.data.Db.Model(&models.Storyboard{}).Where("id = ?", reply.Id).Update("status", int32(pb.StoryboardStatusEnum_SECTION_STATUS_VIDEO_IN_PRODUCTION))
	if result.Error != nil {
		log.Error(result.Error)
		return nil
	}
	result = p.data.Db.Model(&models.StoryboardSection{}).Where("storyboard_id = ?", reply.Id).Update("status", int32(pb.StoryboardStatusEnum_SECTION_STATUS_VIDEO_IN_PRODUCTION))
	if result.Error != nil {
		log.Error(result.Error)
		return nil
	}

	return err
}

func (p *ProduceData) ReqProduceCreate(reply *pb.GetStoryboardReply) {
	if reply == nil {
		log.Error("reply is nil")
		return
	}
	log.Info("触发一个视频合成请求 storyId:", reply.Id)
	defer func(id int32) {
		if r := recover(); r != nil {
			log.Info("ReqProduceCreate Recovered in f", r, "id= ", id)
		}
	}(reply.Id)

	// 拼装一下数据 发送给produce服务 生产请求
	for _, section := range reply.Sections {
		//backAsset := p.AssetData.AssetMap[int64(section.Background.Asset.Id)]
		humanAsset := p.AssetData.AssetMap[int(section.Human.Asset.Id)]
		splitHuman := strings.Split(humanAsset.Payload, ".")
		ctx := context.Background()
		fmt.Println("-----------")
		fmt.Println(section.Background)
		fmt.Println(section)
		fmt.Println("-----------")
		if section.Background.Asset.Thumbnail == "" || splitHuman[0] == "" || section.Text.Url == "" {
			log.Error("参数不全，无法生产视频 请检查数据是否完整 section_id = ", section.Id, "storyboard_id = ", reply.Id)
			return
		}

		reqData := &v1.CreateProduceRequest{
			StoryboardId:        reply.Id,
			StoryboardSectionId: section.Id,
			BackgroundUri:       section.Background.Asset.Thumbnail,
			FaceVideo:           splitHuman[0], // C3025 标识
			AudionUri:           section.Text.Url,
			Payload: &v1.Payload{
				X:      section.Human.X,
				Y:      section.Human.Y,
				Width:  section.Human.Width,
				Height: section.Human.Height,
			},
		}
		fmt.Println(reqData)
		rsp, err := p.produceHttpServer.CreateProduce(ctx, reqData)
		if err != nil {
			log.Error(err)
			return
		}
		// 打印返回结果
		println("请求生产视频服务返回结果： ", rsp.Message, rsp.Code)
	}

	// 更新一下storyboard的状态为视频制作中 目前只有一个场景
	result := p.data.Db.Model(&models.Storyboard{}).Where("id = ?", reply.Id).Update("status", int32(pb.StoryboardStatusEnum_SECTION_STATUS_VIDEO_IN_PRODUCTION))
	if result.Error != nil {
		log.Error(result.Error)
		return
	}
	result = p.data.Db.Model(&models.StoryboardSection{}).Where("storyboard_id = ?", reply.Id).Update("status", int32(pb.StoryboardStatusEnum_SECTION_STATUS_VIDEO_IN_PRODUCTION))
	if result.Error != nil {
		log.Error(result.Error)
		return
	}

	return
}
